const tool = require('./build/Release/addon.node')

window = globalThis
let all_temp = []
!function () {
  Object.defineProperty(window, "HTMLAllCollection", {
    value: tool.CreateConstructor("HTMLAllCollection"), writable: true, enumerable: false, configurable: true
  });
  Object.prototype.HTMLAllCollection = {
    new(ownerDocument) {
      let obj = tool.Document_All({
        callAsFunction() {
          let value = null;
          if (Object.getOwnPropertyNames(all_temp).includes("" + arguments[0])) {
            value = all_temp[arguments[0]];
          }
          let msg = { '调用者': 'HTMLAllCollection作为函数执行', '参数': arguments[0], '返回值': value };
          console.log(msg);
          return value;
        },
        getter(target, property) {
          let index = 0, value = undefined;
          function find(nodeArray) {
            for (let i in nodeArray) {
              if (typeof (property) == "number") {
                if (index == property) { value = nodeArray[i]; break; }
                index += 1;
              } else if (typeof (property) == "string") {
                if (i == property) { value = nodeArray[i]; break; }
                index += 1;
              }
            }
          }
          find(all_temp);

          let msg = { '调用者': 'HTMLAllCollection', '属性': property, '返回值': all_temp[property] };
          console.log(msg);

          if (value) {
            return { value: value, intercept: true };
          } else {
            return { value: undefined, intercept: false };
          }
        },
        query(target, property) {
          console.log("请求all属性：",property);
          
          let index = 0, value = undefined;
          function find(nodeArray) {
            for (let i in nodeArray) {
              if (typeof (property) == "number") {
                if (index == property) { value = nodeArray[i]; break; }
                index += 1;
              } else if (typeof (property) == "string") {
                if (i == property) { value = nodeArray[i]; break; }
                index += 1;
              }
            }
          }
          find(all_temp);
          if (value) {
            if (typeof (property) == "number") {
              return {
                value: { value: value, writable: false, enumerable: true, configurable: true },
                intercept: true,
              };
            } else if (typeof (property) == "string") {
              return {
                value: { value: value, writable: false, enumerable: false, configurable: true },
                intercept: true,
              };
            }
          } else {
            return { intercept: false };
          }
        },
        descriptor(target, property) {
          let index = 0, value = undefined;
          function find(nodeArray) {
            for (const i in nodeArray) {
              if (typeof (property) == "number") {
                if (index == property) { value = nodeArray[i]; break; }
                index += 1;
              } else if (typeof (property) == "string") {
                if (i == property) { value = nodeArray[i]; break; }
                index += 1;
              }
            }
          }
          find(all_temp);
          if (value) {
            if (typeof (property) == "number") {
              return {
                value: { value: value, writable: false, enumerable: true, configurable: true },
                intercept: true,
              };
            } else if (typeof (property) == "string") {
              return {
                value: { value: value, writable: false, enumerable: false, configurable: true },
                intercept: true,
              };
            }
          } else {
            return { intercept: false };
          }
        },
        enumerator(target) {
          const nameAry = Object.keys(all_temp);
          const indexAry = [];
          for (let i = 0; i < nameAry.length; i++) {
            indexAry.push(i);
          }
          return {
            value: [...nameAry, ...indexAry],
            intercept: true,
          };
        },
      });
      Object.setPrototypeOf(obj, HTMLAllCollection.prototype);
      return obj;
    },
  };
  Object.defineProperties(HTMLAllCollection, {
    prototype: { value: HTMLAllCollection.prototype, writable: false, enumerable: false, configurable: false },
  });
  Object.defineProperties(HTMLAllCollection.prototype, {
    length: {
      get: tool.CreateGetter("length", function length() {
        return Object.keys(this).length;
      }), set: undefined, enumerable: true, configurable: true,
    },
    item: {
        value: tool.CreateAction("item", 0, function item() {
            return this[arguments[0]];
        }), writable: true, enumerable: true, configurable: true,
    },
    namedItem: {
        value: tool.CreateAction("namedItem", 1, function namedItem() {
            return this[arguments[0]];
        }), writable: true, enumerable: true, configurable: true,
    },
    constructor: { writable: true, enumerable: false, configurable: true, value: HTMLAllCollection },
    [Symbol.toStringTag]: { value: "HTMLAllCollection", writable: false, enumerable: false, configurable: true, },
    [Symbol.iterator]: {
        value: tool.CreateAction("values", 0, function* values() {
            for (const key of Object.keys(this)) {
                yield this[key];
            }
        }), writable: true, enumerable: false, configurable: true,
    },
  });


  Object.defineProperties(HTMLAllCollection.prototype, {
    constructor: { writable: true, enumerable: false, configurable: true, value: HTMLAllCollection },
    [Symbol.toStringTag]: { value: "HTMLAllCollection", writable: false, enumerable: false, configurable: true, },
  });
}();
document = {}
document.all = Object.prototype.HTMLAllCollection.new()

// 使用 Object.defineProperty 定义数组中索引 0 的属性
Object.defineProperty(all_temp, 0, {
  value: { "head": "2133" },
  writable: true,
  enumerable: true,
  configurable: true
});
Object.defineProperty(all_temp, "ccc", {
  value: { "cccc": "d123" },
  writable: true,
  enumerable: true,
  configurable: true
});
console.log(document.all("ccc"))
console.log(document.all["ccc"])

console.log(Object.getOwnPropertyDescriptors(document.all))
console.log(document.all.length)
// debugger


// debugger
!function () {
  try {
    if (document.all.__proto__ === HTMLAllCollection.prototype) {
      if (document.all !== undefined) {
        if (document.all == undefined) {//typeof document.all 类型是undefined 这里检测不好过，类型是undefined，但是对象上又有属性，JS环境无法实现或不好实现，在node环境可以实现
          console.log("环境正常");
        } else {
          console.log("环境异常3");
        }
      } else {
        console.log("环境异常2");
      }
    } else {
      console.log("环境异常1");
    }
  } catch (e) {
    console.log("环境异常0");
  }
}();

(function () {
  try {
    const all = document.all;
    if (HTMLAllCollection.prototype.constructor != HTMLAllCollection) {
      console.log("浏览器环境异常，校验失败！");
      return;
    }
    if (HTMLAllCollection.name != "HTMLAllCollection" || HTMLAllCollection.length != 0) {
      console.log("浏览器环境异常，校验失败！");
      return;
    }
    if (all.__proto__ != HTMLAllCollection.prototype) {
      console.log("浏览器环境异常，校验失败！");
      return;
    }
    if (all != undefined || typeof all != 'undefined') {
      console.log("浏览器环境异常，校验失败！");
      return;
    }
    if (all.length < 1) {
      console.log("浏览器环境异常，校验失败！");
      return;
    }
    console.log("浏览器环境正常，校验通过！");
  } catch (e) {
    console.log("浏览器环境异常，校验失败！");
  }
}())
document.all['length']
if ('length' in document.all) {
}
if (2222 in document.all) {
}
if (function () { } in document.all) {
}

document.all['2222222'] = 'null';
document.all['2222222']
console.log(document.all.item("0"))
debugger

console.log(document.all[0] === document.all(0));
console.log(document.all[0] == document.all(0));